/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef HMFS_MKFS_FORMAT_H
#define HMFS_MKFS_FORMAT_H

#include <memory>
#include <string>
#include <sys/types.h>

#include "hmfs_data.h"
#include "hmfs_command.h"
#include "area_formater.h"
#include "super_block_writer.h"

namespace OHOS {
namespace Hmfs {

struct HmfsData {
    // std::vector<DeviceInfo> deviceList;

    uint32_t sectorSize;
    uint32_t sectorsPerBlk = DEFAULT_SECTORS_PER_BLK;
    uint32_t segsPerZone = 1;
    uint64_t sectorCount = 0;
    uint32_t startSector = 0;
    size_t blocksPerZone;

    uint64_t zoneAlignStartOffset;
    uint32_t segment0BlkId;

    uint32_t segmentCount = 0;
    uint32_t zoneAlignedSegCount;
    uint32_t segmentCountInCP = HMFS_CP_COUNT;

    uint32_t sitStartBlkId;
    uint32_t segmentCountInSIT;

    uint32_t natStartBlkId;
    uint32_t segmentCountInNAT;

    uint32_t cpPayload;

    uint32_t segmentCountInSSA;

    uint32_t mainStartBlkId;
    uint32_t sectionCount;
    uint32_t segmentCountInMain;

    uint32_t reservedSegments;
    uint32_t nodeInode = 1;
    uint32_t metaInode = 2;
    uint32_t rootInode = 3;
    uint32_t nextFreeInodeId = 4;
    uint32_t qf_ino[MAXQUOTAS];
    uint32_t quotaInodeCount = 0;
    uint32_t quotaDataBlks = 0;
    uint32_t lpfIno = 0;
    uint32_t lpfInum = 0;
    uint32_t lpfDnum = 0;
    uint32_t chksumSeed = 0;
    int32_t zonedModel;

    char version[VERSION_TOTAL_LEN + 1];
    uint32_t curSeg[CURSEG_TYPE_MAX];
};

class HmfsMkfs {
public:
    HmfsMkfs(CmdConfig &cfgPara);
    ~HmfsMkfs() = default;
    int32_t Process();

private:
    friend class CpWriter;
    friend class MainAreaWriter;
    friend class NatWriter;
    friend class SitWriter;
    friend class SuperBlockWriter;

    CmdConfig &cfgPara_;
    HmfsData hmfsData_;
    // SuperBlockWriter superBlockWriter;
    std::vector<std::unique_ptr<HmfsDataAreaFormater>> areaFormaters_;

    inline uint32_t PreviousZone(uint32_t curSegType)
    {
        return hmfsData_.curSeg[curSegType] - hmfsData_.segsPerZone;
    }

    inline uint32_t NextZone(uint32_t curSegType)
    {
        return hmfsData_.curSeg[curSegType] + hmfsData_.segsPerZone;
    }

    inline uint32_t LastZone(uint32_t zoneCount)
    {
        return (zoneCount - 1) * hmfsData_.segsPerZone;
    }

    inline uint32_t LastSection(uint32_t zoneId)
    {
        return zoneId + (cfgPara_.sectionsPerZone - 1) * cfgPara_.segsPerSection;
    }

    int32_t Format();
    int32_t ClacHmfsData();
    void VerifyCurSegData(void);
    int32_t CreateDeviceInfo();
    void CreateFormaters();
    int32_t GetDeviceSectorInfo();
    SuperBlockData* GetSuperBlockData();
    int32_t OverwriteDevices();
    int32_t GetZoneInfo();

};

} // namespace Hmfs
} // namespace OHOS
#endif
